Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ONVIF client #1589

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

fix: ONVIF client #1589

wants to merge 1 commit into from

Conversation

seydx
Copy link
Contributor

@seydx seydx commented Feb 10, 2025

This PR fixes two ONVIF camera compatibility issues:

  1. Some cameras (Tapo with latest fw) send malformed HTTP responses with garbage/null bytes before the actual XML content. Fixed by:
    • Switching from http.Client to direct TCP connection
    • Looking for "<?xml" marker to find start of actual content
    • Using manual HTTP request writing
    • Setting default timeout of 5 seconds
Post "http://192.168.178.131:2020/onvif/device_service": net/http: HTTP/1.x transport connection broken: malformed HTTP status code "/onvif/device_service\x00HTTP/1.1\x00\x00Host\x00"
panic: Post "http://192.168.178.131:2020/onvif/device_service": net/http: HTTP/1.x transport connection broken: malformed HTTP status code "/onvif/device_service\x00HTTP/1.1\x00\x00Host\x00"
  1. Ensure compatibility with all ONVIF cameras by:
    • Setting standard ONVIF paths as defaults (/onvif/media_service, /onvif/imaging_service)
    • Using advertised XAddr values from GetCapabilities when available

Testing: Verified working with cameras that previously failed with:

  • "malformed HTTP status code" errors
  • "unsupported service" errors

@AlexxIT AlexxIT self-assigned this Feb 11, 2025
@vinicius73
Copy link

I have the same issue.
I've tested this code, this PR solve it, thanks.

@AlexxIT could you merge it?

@AlexxIT
Copy link
Owner

AlexxIT commented Feb 17, 2025

PR will be accepted after a careful review.

@AlexxIT
Copy link
Owner

AlexxIT commented Feb 17, 2025

  1. I don't like idea support malformed responses. Especially for one buggy camera. Hopefully Tapo will fix it themselves.
  2. Support "unsupported service" is OK.

Can you fix or split PR?

@AlexxIT AlexxIT removed their assignment Feb 17, 2025
@felipecrs
Copy link
Contributor

felipecrs commented Feb 17, 2025

  1. I don't like idea support malformed responses. Especially for one buggy camera. Hopefully Tapo will fix it themselves.

@AlexxIT you didn't ask but I would like to advocate in @seydx's favor:

I think one of the best things about go2rtc is how fault-tolerant and universal it is.

In the ideal world, all camera manufacturers would implement things following best practices or would release firmware updates fixing stuff.

But real world is very different, in real world you buy a camera and almost never receive a firmware update for it.

And it's amazing how go2rtc works great for the real world.

I don't even have any Tapo cameras, and maybe Tapo is one of the good manufacturers which fixes issues reported by their customers.

But it seems to me that @seydx's fix is generic enough to handle potential issues like this for any future camera that may send malformed responses.

From what I can tell, it doesn't seem that the fix will have a performance penalty.

Also, the code remains simple to me.

Maybe the request logic could be encapsulated in a new class to keep ONVIF client class tidy. And then maybe unit tests could be added to such class, especially to guarantee that it continues to work for previous cameras. But I'm not sure.

Anyway, I'm also in favor of splitting this PR into two.

@AlexxIT
Copy link
Owner

AlexxIT commented Feb 18, 2025

There are many fixes for broken protocols in go2rtc.

Just specifically in this case there is just too much code for a fairly useless situation - ONVIF from some fw from some Tapo cameras.

I've had to use a raw HTTP client elsewhere on go2rtc before. Perhaps after refactoring and merging this code - the fix can be returned.

It is even better to write a test on this fix, so that the crooked response from the camera is fixed there.

@ostehamster
Copy link

ostehamster commented Feb 28, 2025

I updated my setup from v1.9.7 to v1.9.8 the other day and faced the same issue - or at least I think it is the same.

The changes in commit f601c47, "Improve ONVIF server", removed the optional "Category" field from the "GetCapabilities" requests, which makes my Tapo CS320WS send garbage. Adding back the "Category" field fixes it.

I don't know if it is a better fix, but it is at least less code.

diff --git a/pkg/onvif/client.go b/pkg/onvif/client.go
index cb6221e..a859be8 100644
--- a/pkg/onvif/client.go
+++ b/pkg/onvif/client.go
@@ -161,6 +161,8 @@ func (c *Client) GetServiceCapabilities() ([]byte, error) {
 func (c *Client) DeviceRequest(operation string) ([]byte, error) {
 	if operation == DeviceGetServices {
 		operation = `<tds:GetServices><tds:IncludeCapability>true</tds:IncludeCapability></tds:GetServices>`
+        } else if operation == DeviceGetCapabilities {
+               operation = `<tds:GetCapabilities xmlns:tds="http://www.onvif.org/ver10/device/wsdl"><tds:Category>All</tds:Category></tds:GetCapabilities>`
 	} else {
 		operation = `<tds:` + operation + `/>`
 	}

@AlexxIT
Copy link
Owner

AlexxIT commented Mar 1, 2025

@ostehamster fixed 57cd791

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants